using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Drawing.Text;
using System.ComponentModel;

namespace needle.UI.Controls.Flat.Windows.Forms
{
	[DefaultProperty("PopupStyle")]
	public class ImageButton : Control
	{
		protected int mborderWidth;
		protected bool mmouseOver;
		protected bool mmouseCapture;
		protected bool mpopupStyle;
		protected int mimageIndexEnabled;
		protected int mimageIndexDisabled;
		protected ImageList mimageList;
		protected ImageAttributes mimageAttr;
		protected MouseButtons mmouseButton;
		
		#region Constructors

		public ImageButton()
		{
			InternalConstruct(null, -1, -1, null);
		}

		public ImageButton(ImageList imageList, int imageIndexEnabled)
		{
			InternalConstruct(imageList, imageIndexEnabled, -1, null);
		}

		public ImageButton(ImageList imageList, int imageIndexEnabled, int imageIndexDisabled)
		{
			InternalConstruct(imageList, imageIndexEnabled, imageIndexDisabled, null);
		}

		public ImageButton(ImageList imageList, int imageIndexEnabled, int imageIndexDisabled, ImageAttributes imageAttr)
		{
			InternalConstruct(imageList, imageIndexEnabled, imageIndexDisabled, imageAttr);
		}
		
		public void InternalConstruct(ImageList imageList, 
			int imageIndexEnabled, 
			int imageIndexDisabled, 
			ImageAttributes imageAttr)
		{
			mimageList = imageList;
			mimageIndexEnabled = imageIndexEnabled;
			mimageIndexDisabled = imageIndexDisabled;
			mimageAttr = imageAttr;

			mborderWidth = 2;
			mmouseOver = false;
			mmouseCapture = false;
			mpopupStyle = true;
			mmouseButton = MouseButtons.None;

			SetStyle(ControlStyles.DoubleBuffer | 
				ControlStyles.AllPaintingInWmPaint |
				ControlStyles.UserPaint, true);
			
			SetStyle(ControlStyles.StandardDoubleClick, false);

			SetStyle(ControlStyles.Selectable, false);
		}

		#endregion

		#region Overrides

		protected override void OnMouseDown(MouseEventArgs e)
		{
			if (!mmouseCapture)
			{
				mmouseOver = true;
				mmouseCapture = true;
				mmouseButton = e.Button;

				Invalidate();
			}

			base.OnMouseDown(e);
		}

		protected override void OnMouseUp(MouseEventArgs e)
		{
			if (e.Button == mmouseButton)
			{
				mmouseOver = false;
				mmouseCapture = false;

				Invalidate();
			}
			else
			{
				Capture = true;
			}

			base.OnMouseUp(e);
		}

		protected override void OnMouseMove(MouseEventArgs e)
		{
			bool over = this.ClientRectangle.Contains(new Point(e.X, e.Y));

			if (over != mmouseOver)
			{
				mmouseOver = over;

				Invalidate();
			}

			base.OnMouseMove(e);
		}

		protected override void OnMouseEnter(EventArgs e)
		{
			mmouseOver = true;

			Invalidate();

			base.OnMouseEnter(e);
		}

		protected override void OnMouseLeave(EventArgs e)
		{
			mmouseOver = false;

			Invalidate();

			base.OnMouseLeave(e);
		}

		protected override void OnPaint(PaintEventArgs e)
		{
			if (mimageList != null)
			{
				if (!this.Enabled)
				{
					if (mimageIndexDisabled != -1)
					{
						if (null == mimageAttr)
						{
							e.Graphics.DrawImage(mimageList.Images[mimageIndexDisabled], new Point(1,1));
						}
						else
						{
							Image image = mimageList.Images[mimageIndexDisabled];

							Point[] pts = new Point[3];
							pts[0].X = 1;
							pts[0].Y = 1;
							pts[1].X = pts[0].X + image.Width;
							pts[1].Y = pts[0].Y;
							pts[2].X = pts[0].X;
							pts[2].Y = pts[1].Y + image.Height;

							e.Graphics.DrawImage(mimageList.Images[mimageIndexDisabled], 
								pts,
								new Rectangle(0, 0, image.Width, image.Height),
								GraphicsUnit.Pixel, mimageAttr);
						}
					}
					else
					{
						if (mimageIndexEnabled != -1)
						{
							ControlPaint.DrawImageDisabled(e.Graphics, mimageList.Images[mimageIndexEnabled], 1, 1, this.BackColor);
						}
						else
						{
						}
					}
				}
				else
				{
					if (null == mimageAttr)
					{
						e.Graphics.DrawImage(mimageList.Images[mimageIndexEnabled], 
							(mmouseOver &&  mmouseCapture ? new Point(2,2) : 
							new Point(1,1)));
					}
					else
					{
						Image image = mimageList.Images[mimageIndexEnabled];

						Point[] pts = new Point[3];
						pts[0].X = (mmouseOver && mmouseCapture) ? 2 : 1;
						pts[0].Y = (mmouseOver && mmouseCapture) ? 2 : 1;
						pts[1].X = pts[0].X + image.Width;
						pts[1].Y = pts[0].Y;
						pts[2].X = pts[0].X;
						pts[2].Y = pts[1].Y + image.Height;

						e.Graphics.DrawImage(mimageList.Images[mimageIndexEnabled], 
							pts,
							new Rectangle(0, 0, image.Width, image.Height),
							GraphicsUnit.Pixel, mimageAttr);
					}

					ButtonBorderStyle bs;

					if (mpopupStyle)
					{
						if (mmouseOver && this.Enabled)
							bs = (mmouseCapture ? ButtonBorderStyle.Inset : ButtonBorderStyle.Outset);
						else
							bs = ButtonBorderStyle.Solid;
					}
					else
					{
						if (this.Enabled)
							bs = ((mmouseOver && mmouseCapture) ? ButtonBorderStyle.Inset : ButtonBorderStyle.Outset);
						else
							bs = ButtonBorderStyle.Solid;
					}

					ControlPaint.DrawBorder(e.Graphics, this.ClientRectangle, 
						this.BackColor, mborderWidth, bs,
						this.BackColor, mborderWidth, bs,
						this.BackColor, mborderWidth, bs,
						this.BackColor, mborderWidth, bs);
				}
			}

			base.OnPaint(e);
		}

		#endregion

		#region Properties

		[Category("Appearance")]
		[DefaultValue(null)]
		public ImageList ImageList
		{
			get { return mimageList; }

			set
			{
				if (mimageList != value)
				{
					mimageList = value;
					Invalidate();
				}
			}
		}

		[Category("Appearance")]
		[DefaultValue(-1)]
		public int ImageIndexEnabled
		{
			get { return mimageIndexEnabled; }

			set
			{
				if (mimageIndexEnabled != value)
				{
					mimageIndexEnabled = value;
					Invalidate();
				}
			}
		}

		[Category("Appearance")]
		[DefaultValue(-1)]
		public int ImageIndexDisabled
		{
			get { return mimageIndexDisabled; }

			set
			{
				if (mimageIndexDisabled != value)
				{
					mimageIndexDisabled = value;
					Invalidate();
				}
			}
		}

		[Category("Appearance")]
		[DefaultValue(null)]
		public ImageAttributes ImageAttributes
		{
			get { return mimageAttr; }
			
			set
			{
				if (mimageAttr != value)
				{
					mimageAttr = value;
					Invalidate();
				}
			}
		}

		[Category("Appearance")]
		[DefaultValue(2)]
		public int BorderWidth
		{
			get { return mborderWidth; }

			set
			{
				if (mborderWidth != value)
				{
					mborderWidth = value;
					Invalidate();
				}
			}
		}

		[Category("Appearance")]
		[DefaultValue(true)]
		public bool PopupStyle
		{
			get { return mpopupStyle; }

			set
			{
				if (mpopupStyle != value)
				{
					mpopupStyle = value;
					Invalidate();
				}
			}
		}

		#endregion
	}
}